This ends up killing two birds with one stone! The rationale behind this is that
the example and bin namespaces are not the same, and we don't mix metadata into
either filename, so the outputs need to be in different locations.
Closes #193
Closes #751
#[deriving(Show, Clone, Hash, PartialEq, Encodable)]
pub enum TargetKind {
LibTarget(Vec<LibKind>),
- BinTarget
+ BinTarget,
+ ExampleTarget,
}
#[deriving(Encodable, Decodable, Clone, PartialEq, Show)]
fn encode(&self, s: &mut S) -> Result<(), E> {
let kind = match self.kind {
LibTarget(ref kinds) => kinds.iter().map(|k| k.crate_type()).collect(),
- BinTarget => vec!("bin")
+ BinTarget => vec!("bin"),
+ ExampleTarget => vec!["example"],
};
SerializedTarget {
pub fn example_target(name: &str, src_path: &Path, profile: &Profile) -> Target {
Target {
- kind: BinTarget,
+ kind: ExampleTarget,
name: name.to_string(),
src_path: src_path.clone(),
profile: profile.clone(),
}
}
- /// Returns true for binary, bench, tests and examples.
+ /// Returns true for binary, bench, and tests.
pub fn is_bin(&self) -> bool {
match self.kind {
BinTarget => true,
}
}
+ /// Returns true for exampels
+ pub fn is_example(&self) -> bool {
+ match self.kind {
+ ExampleTarget => true,
+ _ => false
+ }
+ }
+
pub fn get_profile(&self) -> &Profile {
&self.profile
}
LibTarget(ref kinds) => {
kinds.iter().map(|kind| kind.crate_type()).collect()
},
- BinTarget => vec!("bin")
+ ExampleTarget |
+ BinTarget => vec!("bin"),
}
}
}
let stem = target.file_stem();
let mut ret = Vec::new();
- if target.is_bin() || target.get_profile().is_test() {
+ if target.is_example() {
+ ret.push(format!("examples/{}{}", stem, self.target_exe));
+ } else if target.is_bin() || target.get_profile().is_test() {
ret.push(format!("{}{}", stem, self.target_exe));
} else {
if target.is_dylib() {
let (old_root, root) = {
let layout = cx.layout(pkg, kind);
- (layout.old_root().clone(), layout.root().clone())
+ if target.is_example() {
+ (layout.old_examples().clone(), layout.examples().clone())
+ } else {
+ (layout.old_root().clone(), layout.root().clone())
+ }
};
let mut pairs = vec![(old_loc, new_loc.clone())];
if !target.get_profile().is_doc() {
//! # This is the root directory for all output of *dependencies*
//! deps/
//!
+//! # Root directory for all compiled examples
+//! examples/
+//!
//! # This is the location at which the output of all custom build
//! # commands are rooted
//! native/
//! # Same as the two above old directories
//! old-native/
//! old-fingerprint/
+//! old-examples/
//! ```
use std::io::{mod, fs, IoResult};
deps: Path,
native: Path,
fingerprint: Path,
+ examples: Path,
old_deps: Path,
old_root: Path,
old_native: Path,
old_fingerprint: Path,
+ old_examples: Path,
}
pub struct LayoutProxy<'a> {
deps: root.join("deps"),
native: root.join("native"),
fingerprint: root.join(".fingerprint"),
+ examples: root.join("examples"),
old_deps: root.join("old-deps"),
old_root: root.join("old-root"),
old_native: root.join("old-native"),
old_fingerprint: root.join("old-fingerprint"),
+ old_examples: root.join("old-examples"),
root: root,
}
}
try!(fs::mkdir_recursive(&self.root, io::USER_RWX));
}
- if self.old_deps.exists() {
- try!(fs::rmdir_recursive(&self.old_deps));
- }
+ try!(old(&[
+ (&self.old_deps, &self.deps),
+ (&self.old_native, &self.native),
+ (&self.old_fingerprint, &self.fingerprint),
+ (&self.old_examples, &self.examples),
+ ]));
+
if self.old_root.exists() {
try!(fs::rmdir_recursive(&self.old_root));
}
- if self.old_native.exists() {
- try!(fs::rmdir_recursive(&self.old_native));
- }
- if self.old_fingerprint.exists() {
- try!(fs::rmdir_recursive(&self.old_fingerprint));
- }
- if self.deps.exists() {
- try!(fs::rename(&self.deps, &self.old_deps));
- }
- if self.native.exists() {
- try!(fs::rename(&self.native, &self.old_native));
- }
- if self.fingerprint.exists() {
- try!(fs::rename(&self.fingerprint, &self.old_fingerprint));
- }
-
- try!(fs::mkdir(&self.deps, io::USER_RWX));
- try!(fs::mkdir(&self.native, io::USER_RWX));
- try!(fs::mkdir(&self.fingerprint, io::USER_RWX));
try!(fs::mkdir(&self.old_root, io::USER_RWX));
for file in try!(fs::readdir(&self.root)).iter() {
try!(fs::rename(file, &self.old_root.join(file.filename().unwrap())));
}
- Ok(())
+ return Ok(());
+
+ fn old(dirs: &[(&Path, &Path)]) -> IoResult<()> {
+ for &(old, new) in dirs.iter() {
+ if old.exists() {
+ try!(fs::rmdir_recursive(old));
+ }
+ if new.exists() {
+ try!(fs::rename(new, old));
+ }
+ try!(fs::mkdir(new, io::USER_DIR));
+ }
+ Ok(())
+ }
}
pub fn dest<'a>(&'a self) -> &'a Path { &self.root }
pub fn deps<'a>(&'a self) -> &'a Path { &self.deps }
+ pub fn examples<'a>(&'a self) -> &'a Path { &self.examples }
pub fn native(&self, package: &Package) -> Path {
self.native.join(self.pkg_dir(package))
}
pub fn old_dest<'a>(&'a self) -> &'a Path { &self.old_root }
pub fn old_deps<'a>(&'a self) -> &'a Path { &self.old_deps }
+ pub fn old_examples<'a>(&'a self) -> &'a Path { &self.old_examples }
pub fn old_native(&self, package: &Package) -> Path {
self.old_native.join(self.pkg_dir(package))
}
let _ = fs::rmdir_recursive(&self.old_root);
let _ = fs::rmdir_recursive(&self.old_native);
let _ = fs::rmdir_recursive(&self.old_fingerprint);
+ let _ = fs::rmdir_recursive(&self.old_examples);
}
}
}
pub fn deps(&self) -> &'a Path { self.root.deps() }
+ pub fn examples(&self) -> &'a Path { self.root.examples() }
+
pub fn native(&self, pkg: &Package) -> Path { self.root.native(pkg) }
pub fn old_root(&self) -> &'a Path {
if self.primary {self.root.old_dest()} else {self.root.old_deps()}
}
+ pub fn old_examples(&self) -> &'a Path { self.root.old_examples() }
+
pub fn old_native(&self, pkg: &Package) -> Path {
self.root.old_native(pkg)
}
fn build_plugin_args(mut cmd: ProcessBuilder, cx: &Context, pkg: &Package,
target: &Target, kind: Kind) -> ProcessBuilder {
cmd = cmd.arg("--out-dir");
- cmd = cmd.arg(cx.layout(pkg, kind).root());
+ if target.is_example() {
+ cmd = cmd.arg(cx.layout(pkg, kind).examples());
+ } else {
+ cmd = cmd.arg(cx.layout(pkg, kind).root());
+ }
let (_, dep_info_loc) = fingerprint::dep_info_loc(cx, pkg, target, kind);
cmd = cmd.arg("--dep-info").arg(dep_info_loc);
let files = fs::readdir(&p.root().join("target")).assert();
let mut files: Vec<String> = files.iter().filter_map(|f| {
match f.filename_str().unwrap() {
- "deps" => None,
+ "examples" | "deps" => None,
s if s.contains("fingerprint") || s.contains("dSYM") => None,
s => Some(s.to_string())
}
let files = fs::readdir(&p.root().join("target")).assert();
let mut files: Vec<String> = files.iter().filter_map(|f| {
match f.filename_str().unwrap() {
- "deps" => None,
+ "examples" | "deps" => None,
s if s.contains("fingerprint") || s.contains("dSYM") => None,
s => Some(s.to_string())
}
"#);
assert_that(p.cargo_process("test"), execs());
- assert_that(process(p.bin("hello")), execs().with_stdout("Hello, World!\n"));
- assert_that(process(p.bin("goodbye")), execs().with_stdout("Goodbye, World!\n"));
+ assert_that(process(p.bin("examples/hello")),
+ execs().with_stdout("Hello, World!\n"));
+ assert_that(process(p.bin("examples/goodbye")),
+ execs().with_stdout("Goodbye, World!\n"));
})
test!(implicit_examples {
"#);
assert_that(p.cargo_process("test"), execs().with_status(0));
- assert_that(process(p.bin("hello")), execs().with_stdout("Hello, World!\n"));
- assert_that(process(p.bin("goodbye")), execs().with_stdout("Goodbye, World!\n"));
+ assert_that(process(p.bin("examples/hello")),
+ execs().with_stdout("Hello, World!\n"));
+ assert_that(process(p.bin("examples/goodbye")),
+ execs().with_stdout("Goodbye, World!\n"));
})
test!(standard_build_no_ndebug {
", compiling = COMPILING, running = RUNNING, dir = p.url(),
doctest = DOCTEST).as_slice()));
})
+
+test!(example_bin_same_name {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+ "#)
+ .file("src/bin/foo.rs", r#"fn main() { println!("bin"); }"#)
+ .file("examples/foo.rs", r#"fn main() { println!("example"); }"#);
+
+ assert_that(p.cargo_process("test").arg("--no-run").arg("-v"),
+ execs().with_status(0)
+ .with_stdout(format!("\
+{compiling} foo v0.0.1 ({dir})
+{running} `rustc [..]bin[..]foo.rs [..] --test [..]`
+{running} `rustc [..]bin[..]foo.rs [..]`
+{running} `rustc [..]examples[..]foo.rs [..]`
+", compiling = COMPILING, running = RUNNING, dir = p.url()).as_slice()));
+
+ assert_that(&p.bin("foo"), existing_file());
+ assert_that(&p.bin("examples/foo"), existing_file());
+
+ assert_that(p.process(p.bin("foo")),
+ execs().with_status(0).with_stdout("bin\n"));
+ assert_that(p.process(p.bin("examples/foo")),
+ execs().with_status(0).with_stdout("example\n"));
+})